EXCEPTION_MAXIMUM_PARAMETERS = 15

DBG_CONTINUE                         = 00010002h
DBG_TERMINATE_THREAD                 = 40010003h
DBG_TERMINATE_PROCESS                = 40010004h
DBG_CONTROL_C                        = 40010005h
DBG_CONTROL_BREAK                    = 40010008h
DBG_EXCEPTION_NOT_HANDLED            = 80010001h

EXCEPTION_DEBUG_EVENT                = 1
CREATE_THREAD_DEBUG_EVENT            = 2
CREATE_PROCESS_DEBUG_EVENT           = 3
EXIT_THREAD_DEBUG_EVENT              = 4
EXIT_PROCESS_DEBUG_EVENT             = 5
LOAD_DLL_DEBUG_EVENT                 = 6
UNLOAD_DLL_DEBUG_EVENT               = 7
OUTPUT_DEBUG_STRING_EVENT            = 8
RIP_EVENT                            = 9

CONTEXT_i386 = 00010000h
CONTEXT_i486 = 00010000h
CONTEXT_CONTROL = CONTEXT_i386 OR 00000001h
CONTEXT_INTEGER = CONTEXT_i386 OR 00000002h
CONTEXT_SEGMENTS = CONTEXT_i386 OR 00000004h
CONTEXT_FLOATING_POINT = CONTEXT_i386 OR 00000008h
CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 OR 00000010h
CONTEXT_FULL = CONTEXT_CONTROL OR CONTEXT_INTEGER OR CONTEXT_SEGMENTS



struct EXCEPTION_RECORD
  .ExceptionCode      dd ?
  .ExceptionFlags     dd ?
  .ptrExceptionRecord dd ?
  .ExceptionAddress   dd ?
  .NumberParameters   dd ?
  .ExceptionInformation rd EXCEPTION_MAXIMUM_PARAMETERS
ends

struct EXCEPTION_DEBUG_INFO
  .ExceptionRecord EXCEPTION_RECORD
  .dwFirstChance dd ?
ends

struct CREATE_THREAD_DEBUG_INFO
  .hThread               dd  ?
  .lpThreadLocalBase     dd  ?
  .lpStartAddress        dd  ?
ends

struct CREATE_PROCESS_DEBUG_INFO
  .hFile                 dd  ?
  .hProcess              dd  ?
  .hThread               dd  ?
  .lpBaseOfImage         dd  ?
  .dwDebugInfoFileOffset dd  ?
  .nDebugInfoSize        dd  ?
  .lpThreadLocalBase     dd  ?
  .lpStartAddress        dd  ?
  .lpImageName           dd  ?
  .fUnicode              dw  ?
ends


struct EXIT_THREAD_DEBUG_INFO
  .dwExitCode  dd      ?
ends

struct EXIT_PROCESS_DEBUG_INFO
  .dwExitCode  dd      ?
ends


struct LOAD_DLL_DEBUG_INFO
  .hFile                     dd   ?
  .lpBaseOfDll               dd   ?
  .dwDebugInfoFileOffset     dd   ?
  .nDebugInfoSize            dd   ?
  .lpImageName               dd   ?
  .fUnicode                  dw   ?
ends


struct UNLOAD_DLL_DEBUG_INFO
  .lpBaseOfDll  dd  ?
ends


struct OUTPUT_DEBUG_STRING_INFO
  .lpDebugStringData     dd    ?
  .fUnicode              dw    ?
  .nDebugStringiLength   dw    ?
ends


struct RIP_INFO
  .dwError  dd  ?
  .dwType   dd  ?
ends


SIZE_OF_80387_REGISTERS   = 80
MAXIMUM_SUPPORTED_EXTENSION = 512

struct FLOATING_SAVE_AREA
  .ControlWord   dd      ?
  .StatusWord    dd      ?
  .TagWord       dd      ?
  .ErrorOffset   dd      ?
  .ErrorSelector dd      ?
  .DataOffset    dd      ?
  .DataSelector  dd      ?
  .RegisterArea  rb SIZE_OF_80387_REGISTERS
  .Cr0NpxState   dd      ?
ends

struct CONTEXT
  .ContextFlags  dd      ?
  .iDr0          dd      ?
  .iDr1          dd      ?
  .iDr2          dd      ?
  .iDr3          dd      ?
  .iDr6          dd      ?
  .iDr7          dd      ?
  .FloatSave     FLOATING_SAVE_AREA
  .regGs         dd      ?
  .regFs         dd      ?
  .regEs         dd      ?
  .regDs         dd      ?
  .regEdi        dd      ?
  .regEsi        dd      ?
  .regEbx        dd      ?
  .regEdx        dd      ?
  .regEcx        dd      ?
  .regEax        dd      ?
  .regEbp        dd      ?
  .regEip        dd      ?
  .regCs         dd      ?
  .regFlag       dd      ?
  .regEsp        dd      ?
  .regSs         dd      ?
  .ExtendedRegisters rb MAXIMUM_SUPPORTED_EXTENSION
ends


struct SECURITY_ATTRIBUTES
  .nLength              dd ?
  .lpSecurityDescriptor dd ?
  .bInheritHandle       dd ?
ends


..TryLevel = 0

macro beginTry {
  common
    ptrExceptionContext equ esp+$0c
    ptrExceptionRecord  equ esp+$04

    local ..handler, ..endtry
    end@try equ ..endtry

  if defined ..handler
        ..TryLevel = ..TryLevel+1
        pushd   ..handler
        pushd   [fs:0]
        mov     [fs:0], esp
  end if

  macro onException _%e
        jmp     ..endtry
    ..handler:
  e%_

  macro Ignore _%e
        mov     eax, [ptrExceptionContext]
        mov     [eax+CONTEXT.regEip], ..endtry
        xor     eax, eax
        retn
  e%_

  macro Retry _%e
        xor     eax, eax
        retn
  e%_


  macro Next _%e
        mov     eax, 1
        retn
  e%_

}


macro endTry {
  common
  label end@try
  if ..TryLevel > 0
        popd    [fs:0]
        add     esp, 4
        ..TryLevel = ..TryLevel - 1
  end if
  purge onException
  purge Ignore
  purge Next
  purge Retry
  restore end@try
  restore ptrExceptionContext
  restore ptrExceptionRecord
}



_%e fix {
e%_ fix }


